package fnic.modesearch;

import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.AndFilterBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.GeoDistanceFilterBuilder;
import org.elasticsearch.index.query.OrFilterBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeFilterBuilder;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.facet.Facet;
import org.elasticsearch.search.facet.FacetBuilder;
import org.elasticsearch.search.facet.FacetBuilders;
import org.elasticsearch.search.facet.range.RangeFacet;
import org.elasticsearch.search.facet.range.RangeFacetBuilder;
import org.elasticsearch.search.facet.statistical.StatisticalFacet;
import org.elasticsearch.search.facet.statistical.StatisticalFacetBuilder;
import org.elasticsearch.search.facet.terms.TermsFacet;
import org.elasticsearch.search.facet.terms.TermsFacetBuilder;
import org.elasticsearch.search.facet.termsstats.TermsStatsFacet;
import org.elasticsearch.search.facet.termsstats.TermsStatsFacetBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

import fnic.jsontrans.SearchQueryJsonMode.*;
import fnic.jsontrans.SearchResultJsonMode.*;
import fnic.prehand.common.AgentConfig;
import fnic.prehand.esagent.EsAgent;

public class ModeSearch extends EsAgent{
	private static final AgentConfig config = AgentConfig.getInstance();
	private static final Logger LOG = Logger.getLogger(ModeSearch.class);
	private static final int MAX_SEARCH_DOC_SIZE = 10000;
	private static final String clustername = config.getEsClusterName();
	
	private final String indexName;
	private final String idxtypeName;
	
	SearchModeJsonParser modeParser;
	SearchModeJsonGenerater modeGenerator;
	AndFilterBuilder andFilter;
	List<FacetBuilder> facetList;
	
	public ModeSearch(String idx, String type){
		indexName = idx;
		idxtypeName = type;
	}
	
	private boolean request(String req){
		modeGenerator = new SearchModeJsonGenerater();
		modeParser = new SearchModeJsonParser(modeGenerator);
		modeGenerator.setParser(modeParser);
		return modeParser.root(req);
	}
	
	/*
	 * 根据模板的input来创建查询Filter
	 */
	public void buildFilter() {
		andFilter = new AndFilterBuilder();
		if (modeParser.getIdsParam() != null) {
			idFilter(andFilter, modeParser.getIdsParam());
		}
		if (modeParser.getKwsParam() != null) {
			kwFilter(andFilter, modeParser.getKwsParam());
		}
		if (modeParser.getPresParam() != null) {
			prefixFilter(andFilter, modeParser.getPresParam());
		}
		if (modeParser.getRegexParam() != null) {
			regexFilter(andFilter, modeParser.getRegexParam());
		}
		if (modeParser.getRangesParam() != null) {
			rangeFilter(andFilter, modeParser.getRangesParam());
		}
		if (modeParser.getGeosParam() != null){
			geoFilter(andFilter, modeParser.getGeosParam());
		}
	} 
	
	/*
	 * 根据模板的statistic来创建查询Facet
	 */
	public void buildStatistic() {
		facetList = new ArrayList<FacetBuilder>();
		/*
		 * Term Count Facet
		 */
		if (modeParser.getIntermsStat() != null) {
			termsFacet(facetList, modeParser.getIntermsStat());
		}
		
		/*
		 * terms stat的统计Facet,类似groupby
		 */
		if(modeParser.getInkvsStat()!=null){
			termKVFacet(facetList, modeParser.getInkvsStat());
		}
		
		/*
		 * 数值型Field数学统计Facet
		 */
		if (modeParser.getInfieldStat() != null) {
			fieldstatFacet(facetList, modeParser.getInfieldStat());
		}

		/*
		 * 数值Field范围统计Facet
		 */
		if (modeParser.getInrangegroupsStat() != null) {
			rangeGroupFacet(facetList, modeParser.getInrangegroupsStat());
		}
	}
	
	//完成一次检索请求
	private boolean innerexec(){
		boolean inputexsitfg = modeParser.isInputflg();
		boolean outputexistfg = modeParser.isOutputflg();
		boolean statexistfg = modeParser.isStatflg();
		
		SearchRequestBuilder queryFacetBuilder = client.prepareSearch(indexName).
				setTypes(idxtypeName).setSearchType(SearchType.QUERY_THEN_FETCH);
		
		//filter
		if(inputexsitfg){
			buildFilter();
			queryFacetBuilder.setPostFilter(andFilter);
		}else{
			queryFacetBuilder.setPostFilter(FilterBuilders.matchAllFilter());
		}
		
		//output
		String[] outfields = null;
		if(outputexistfg){
			outfields = modeParser.getOutfields();
//			queryFacetBuilder.addFields(outfields);
		}
		
		//statistic
		if(statexistfg){
			buildStatistic();
			Iterator<FacetBuilder> iter = facetList.iterator();
			while (iter.hasNext()) {
				queryFacetBuilder.addFacet(iter.next().facetFilter(andFilter));
			}
		}
		
		// 调用ES API进行检索操作
		SearchResponse response = queryFacetBuilder.setFrom(0).setSize(MAX_SEARCH_DOC_SIZE).execute().actionGet();
		if (response.status() != RestStatus.OK) {
			// ES模板检索失败 -- es内部检索失败
			LOG.error("allQueryFacet---ES Search inner error");
			return false;
		}

		SearchHits hits = response.getHits();
		if(modeParser.isTotalflg()){
			modeGenerator.setTotalhits(hits.getTotalHits());
		}
		
		if (outputexistfg) {
			for (SearchHit hit : hits) {
				Map<String, Object> fmaps = new HashMap<String, Object>();
				Map<String, Object> allmaps=hit.sourceAsMap();
				for (String fld : outfields) {
					if(fld.equals("_id")){
						fmaps.put(fld, hit.getId());
					}else if(fld.equals("_all")){
						fmaps=hit.sourceAsMap();
						break;
					}else{
						if(!fld.contains(".")){
							fmaps.put(fld, allmaps.get(fld));
						}else{
							outputLocate(fmaps, allmaps, fld);
						}
					}
				}
				modeGenerator.getHitsoutput().add(fmaps);
			}
		}
		
		if(statexistfg){
			Map<String, Facet> facetMap = response.getFacets().facetsAsMap();
			
			if(modeGenerator.getOuttermStat()!=null){
				for(OutTermFieldStat item : modeGenerator.getOuttermStat()){
					TermsFacet facet = (TermsFacet) facetMap.get("termstat_"+item.getName());
					Map<String, Integer> tcmaps= new HashMap<String, Integer>();
					for (TermsFacet.Entry entry : facet) {
						tcmaps.put(entry.getTerm().toString(), entry.getCount());
					}
					item.setValuecount(tcmaps);
				}
			}
			
			if(modeGenerator.getOutkvsStat()!=null){
				for(OutTermsKVStat item : modeGenerator.getOutkvsStat()){
					TermsStatsFacet facet = (TermsStatsFacet) facetMap.get(item.getName());
					/*
					 * 1  count
					 * 2  min
					 * 3  max 
					 * 4  avg
					 */
					List<Integer> methods=null;
					for(InTermsKVStat termkv : modeParser.getInkvsStat()){
						if(("TermKV_"+termkv.getKeystatfield()+"_"+termkv.getValuestatfield()).equals(item.getName())){
							methods = termkv.getMethod();
							break;
						}
					}						
					if(methods == null){
						//error 找不到对应的
						LOG.error("terms stats facat error, get methods fail by"+item.getName());
					}
					
					List<KeyValueStat> kvlist = new ArrayList<KeyValueStat>();
					for(TermsStatsFacet.Entry entry: facet){
						
						KeyValueStat keyvalue = new KeyValueStat();
						keyvalue.setKeyterm(entry.getTerm().toString());	
						
						
						Map<String, Double> statmaps = new HashMap<String, Double>();
						for(int method : methods){
							switch(method){
							case 0:
								statmaps.put(kvStatName(method), (double)entry.getCount());
								break;
							case 1:
								statmaps.put(kvStatName(method), entry.getMin());
								break;
							case 2:
								statmaps.put(kvStatName(method), entry.getMax());
								break;
							case 3:
								statmaps.put(kvStatName(method), entry.getMean());
								break;
							case 4:
								statmaps.put(kvStatName(method), entry.getTotal());
								break;
							default:
								break;
							}
							
						}
						keyvalue.setValuestat(statmaps);
						kvlist.add(keyvalue);
					}
					item.setValuecount(kvlist);
				}
			}
			
			
			if(modeGenerator.getOutfieldStat()!=null){
				for(OutFieldStat item : modeGenerator.getOutfieldStat()){
					StatisticalFacet facet = (StatisticalFacet) facetMap.get("fieldstat_"+item.getName());
					List<Integer> methods=null;
					for(InNumFieldStat fieldstat : modeParser.getInfieldStat()){
						if(fieldstat.getName().equals(item.getName())){
							methods = fieldstat.getMethod();
						}
					}
					if(methods == null){
						//error 找不到对应的
						LOG.error("field statistic facat error, get methods fail by "+item.getName());
					}
					
					Map<String, Double> statmaps = new HashMap<String, Double>();
					for(int method : methods){
						switch(method){
						case 0:
							statmaps.put(fieldStatName(method), (double)facet.getCount());
							break;
						case 1:
							statmaps.put(fieldStatName(method), facet.getMin());
							break;
						case 2:
							statmaps.put(fieldStatName(method), facet.getMax());
							break;
						case 3:
							statmaps.put(fieldStatName(method), facet.getMean());
							break;
						case 4:
							statmaps.put(fieldStatName(method), facet.getTotal());
							break;
						case 5:
							statmaps.put(fieldStatName(method), facet.getStdDeviation());
							break;
						case 6:
							statmaps.put(fieldStatName(method), facet.getSumOfSquares());
							break;
						case 7:
							statmaps.put(fieldStatName(method), facet.getVariance());
							break;
						default:
							break;
						}
					}
					item.setResobj(statmaps);
				}
			}
			
			if(modeGenerator.getOutrangegroupsStat()!=null){
				for(OutRangesGroupStat item: modeGenerator.getOutrangegroupsStat()){
					RangeFacet facet = (RangeFacet) facetMap.get("groupstat_"+item.getName());
					List<Map<String, Double>> rangestatlists= new ArrayList<Map<String, Double>>();		
					
					List<Integer> methods=null;
					for(InRangesGroupStat rangefieldstat : modeParser.getInrangegroupsStat()){
						if(rangefieldstat.getName().equals(item.getName())){
							methods = rangefieldstat.getMethod();
						}
					}
					if(methods == null){
						//error 找不到对应的
						LOG.error("field range statistic facat error, get methods fail by "+item.getName());
					}
					
					
					for(RangeFacet.Entry entry : facet){
						Map<String, Double> statmaps = new HashMap<String, Double>();
						for(int method : methods){
							switch(method){
							case 0:
								statmaps.put(fieldRangeStatName(method), (double)entry.getCount()); 
								break;
							case 1:
								statmaps.put(fieldRangeStatName(method), entry.getFrom());
								break;
							case 2:
								statmaps.put(fieldRangeStatName(method), entry.getTo());
								break;
							case 3:
								statmaps.put(fieldRangeStatName(method), entry.getMin());
								break;
							case 4:
								statmaps.put(fieldRangeStatName(method), entry.getMax());
								break;
							case 5:
								statmaps.put(fieldRangeStatName(method), entry.getMean());
								break;
							case 6:
								statmaps.put(fieldRangeStatName(method), entry.getTotal());
								break;
							default:
								break;
							}
						}
						rangestatlists.add(statmaps);
					}
					
					item.setResobj(rangestatlists);
				}
			}
		}
		
		return true;
	}
	
	/*
	 * -1 外层tree解析失败
	 * -2 内层input output statistic解析都不成功
	 * -3 es查询失败
	 * -4 bulk 内层input output statistic解析都不成功
	 * -5 bulk es查询失败
	 */
	public void execuate(String requeststr, ModeSearchRuesult moderesult){
		if(!request(requeststr)){
			moderesult.setExecode(-1);
			return;
		}
		
		if(modeParser.isBulkfg()){
			modeGenerator.startbulkjson();
			while (modeParser.hasparse()) {
				if (modeParser.nextparse()) {
					boolean res = innerexec();
					if (!res) {
						moderesult.setExecode(-5);
						return;
					}
					modeGenerator.bulkjsonitem();
				} else {
					moderesult.setExecode(-4);
					return;
				}
			}
			modeGenerator.endbulkjson();
			String result = modeGenerator.bulkjsonOut();
			moderesult.setResult(result);
		}else{
			if(modeParser.parse()){
				boolean res = innerexec();
				if(!res){
					moderesult.setExecode(-3);
					return;
				}
				String result =  modeGenerator.jsonOut();
				moderesult.setResult(result);
			}else{
				moderesult.setExecode(-2);
				return;
			}
		}
		
		modeGenerator.close();
	}

	
	/*=========================构造查询条件Input==============================*/
	
	private void idFilter(AndFilterBuilder filterbuilder, IdsQueryParam[] idList) {
		for(IdsQueryParam ids : idList){
			List<String> idsvalue = ids.getValue();
			String[] idsarr = new String[idsvalue.size()];
			Iterator<String> itor = idsvalue.iterator();
			int counter = 0;
			while(itor.hasNext()){
				idsarr[counter++] = new String(itor.next());
			}
			filterbuilder.add(FilterBuilders.idsFilter().addIds(idsarr));
		}
	}
	
	private void kwFilter(AndFilterBuilder filterbuilder, KeyWordQueryParam[] kwList) {
		for(KeyWordQueryParam kw : kwList){
			filterbuilder.add(FilterBuilders.termsFilter(kw.getName(),kw.getValue()));
		}
	}

	private void prefixFilter(AndFilterBuilder filterbuilder, PrefixQueryParam[] prefixList) {
		for(PrefixQueryParam item : prefixList){
			OrFilterBuilder orFilter = new OrFilterBuilder();
			String fieldname = item.getName();
			List<String> values = item.getValue();
			for(String valueor : values){
				orFilter.add(FilterBuilders.prefixFilter(fieldname,valueor));
			}
			filterbuilder.add(orFilter);
		}
	}
	
	private void regexFilter(AndFilterBuilder filterbuilder, RegexQueryParam[] regexList) {
		for(RegexQueryParam item : regexList){
			OrFilterBuilder orFilter = new OrFilterBuilder();
			String fieldname = item.getName();
			List<String> values = item.getValue();
			for(String valueor : values){
				orFilter.add(FilterBuilders.regexpFilter(fieldname, ".*"+valueor+".*"));
			}
			filterbuilder.add(orFilter);
		}
	}

	private void rangeFilter(AndFilterBuilder filterbuilder, RangeQueryParam[] rangeList) {
		for (RangeQueryParam item : rangeList) {
			OrFilterBuilder orFilter = new OrFilterBuilder();
			String fieldname = item.getName();
			List<FromTo> values = item.getValue();
			for (FromTo ft : values) {
//				orFilter.add(FilterBuilders.rangeFilter(fieldname)
//						.gte(ft.getFrom()).lt(ft.getTo()));
				RangeFilterBuilder rangefilter = FilterBuilders.rangeFilter(fieldname);
				if(ft.getFrom()!=null){
					rangefilter.gte(ft.getFrom());
				}
				if(ft.getTo()!=null){
					rangefilter.lt(ft.getTo());
				}
				orFilter.add(rangefilter);
			}
			filterbuilder.add(orFilter);
		}
	}

	private void geoFilter(AndFilterBuilder filterbuilder, GEOQueryParam[] geos) {
		for (GEOQueryParam item : geos) {
			OrFilterBuilder orFilter = new OrFilterBuilder();
			String fieldname = item.getName();
			List<PositionCycle> values = item.getValue();
			for (PositionCycle dis : values) {
				orFilter.add(FilterBuilders.geoDistanceFilter(fieldname)
						.point(dis.getLat(), dis.getLon())
						.distance(dis.getRadius(), DistanceUnit.METERS)
						.optimizeBbox("memory").geoDistance(GeoDistance.ARC));
			}
			filterbuilder.add(orFilter);
		}
	}
	
	
	
	/*==========================构造结果统计 Facet==============================*/
	/*
	 * Term Count Facet
	 */
	private void termsFacet(List<FacetBuilder> facetList, InTermFieldStat[] termsStat){
		for(InTermFieldStat item : termsStat){
			String fieldname = item.getName();
			TermsFacetBuilder facet = FacetBuilders.termsFacet("termstat_"+fieldname).field(fieldname).size(10);
			facetList.add(facet);
		}
	}
	
	/*
	 * Term Stat Facet
	 */
	private void termKVFacet(List<FacetBuilder> facetList, InTermsKVStat[] termKvStat){
		for(InTermsKVStat item : termKvStat){		
			String keyfield = item.getKeystatfield();
			String valuefield = item.getValuestatfield();
			TermsStatsFacetBuilder facet = FacetBuilders.termsStatsFacet("TermKV_"+keyfield+"_"+valuefield).keyField(keyfield).valueField(valuefield);
			facetList.add(facet);
		}
	}
	
	/*
	 * field Facet
	 */
	private void fieldstatFacet(List<FacetBuilder> facetList, InNumFieldStat[] fieldStat){
		for(InNumFieldStat item : fieldStat){
			String fieldname = item.getName();
			StatisticalFacetBuilder facet = FacetBuilders.statisticalFacet("fieldstat_"+fieldname).field(fieldname);
			facetList.add(facet);
		}
	}
	
	/*
	 * Range Facet
	 */
	private void rangeGroupFacet(List<FacetBuilder> facetList, InRangesGroupStat[] rangeGroupsStat){
		for (InRangesGroupStat item : rangeGroupsStat) {
			boolean isfirst = true;
			String fieldname = item.getName();
			RangeFacetBuilder facet = FacetBuilders.rangeFacet("groupstat_"+fieldname).field(fieldname);

			Iterator<FromTo> rangeItor = item.getRanges().iterator();
			while (rangeItor.hasNext()) {
				FromTo fromto = rangeItor.next();
				String down = fromto.getFrom();
				String up = fromto.getTo();
				if (isfirst) {
					facet.addUnboundedFrom(down);
					isfirst = false;
				}
				if (!down.equals(up)) {
					facet.addRange(down, up);
				}
				if (!rangeItor.hasNext()) {
					facet.addUnboundedTo(up);
				}
			}
			facetList.add(facet);
		}
	}
	
	/*==========================新版本构造结果统计 Aggregation==============================*/
	
	
	
	/*
	 * 获取field字段的中间数
	 */
	private HashMap<String, Double> getFieldMidValue(boolean inputfg) {
		boolean queryExist = false;
		boolean filterExist = false;
		HashMap<String, Double> midSet = new HashMap<String, Double>();

		SearchRequestBuilder countBuilder = client.prepareSearch(indexName)
				.setTypes(idxtypeName).setSearchType(SearchType.COUNT);

		SearchRequestBuilder midValueBuilder = client.prepareSearch(indexName)
				.setTypes(idxtypeName)
				.setSearchType(SearchType.QUERY_AND_FETCH);

		// Filter过滤
		if (inputfg) {
			countBuilder.setPostFilter(andFilter);
			midValueBuilder.setPostFilter(andFilter);
		} else {
			countBuilder.setPostFilter(FilterBuilders.matchAllFilter());
			midValueBuilder.setPostFilter(FilterBuilders.matchAllFilter());
		}

		// 调用ES API进行检索操作
		SearchResponse numCountRsp = countBuilder.setExplain(true).execute()
				.actionGet();

		long ntotalHits = numCountRsp.getHits().getTotalHits();
		int from = 0;
		int midSize = 0;
		if (ntotalHits > Integer.MAX_VALUE) {
			// error 无法获取
		} else {
			int num = (int) ntotalHits;
			// num:奇数，取中间一个
			// num:偶数，取中间2个
			if (num % 2 == 0) {
				from = num / 2 - 1;
				midSize = 2;
			} else {
				from = num / 2;
				midSize = 1;
			}
		}

		// 需要取中间值的Field，需要保证该field是数值类型
		if (modeParser.isStatflg() && modeParser.getInfieldStat() != null) {
			for (InNumFieldStat fieldStatItem : modeParser.getInfieldStat()) {
				if (fieldStatItem.getMethod().contains(8)) {
					String fname = fieldStatItem.getName();

					// 按照fieldName进行排序，取中间位置的取值
					FieldSortBuilder fieldSort = SortBuilders.fieldSort(fname)
							.order(SortOrder.ASC);
					SearchResponse midFieldRsp = midValueBuilder
							.addField(fname).addSort(fieldSort).setFrom(from)
							.setSize(midSize).execute().actionGet();

					SearchHits hits = midFieldRsp.getHits();

					int sizer = 0;
					double sum = 0;
					for (SearchHit hit : hits) {
						Map<String, SearchHitField> fieldmap = hit.getFields();
						sum += (Double) fieldmap.get(fname).getValue();
						sizer++;
					}
					// System.out.println("sum:"+sum+", sizer:"+sizer);
					double midValue;
					// 设置中间取值
					if (sizer != 0) {
						midValue = sum / sizer;
					} else {
						midValue = 0;
					}

					// 添加一个<string, double> mid对象
					midSet.put(fname, midValue);
				}
			}
		}

		return midSet;
	}

	private String kvStatName(int index) {
		String statname;
		switch (index) {
		case 0:
			statname = "count";
			break;
		case 1:
			statname = "min";
			break;
		case 2:
			statname = "max";
			break;
		case 3:
			statname = "avg";
			break;
		case 4:
			statname = "sum";
			break;
		default:
			statname = "unkown";
			break;
		}
		return statname;
	}

	private String fieldStatName(int index) {
		String statname;
		switch (index) {
		case 0:
			statname = "count";
			break;
		case 1:
			statname = "min";
			break;
		case 2:
			statname = "max";
			break;
		case 3:
			statname = "avg";
			break;
		case 4:
			statname = "sum";
			break;
		case 5:
			statname = "stdev";
			break;
		case 6:
			statname = "sumsquare";
			break;
		case 7:
			statname = "var";
			break;
		case 8:
			statname = "mid";
			break;
		default:
			statname = "unkown";
		}
		return statname;
	}

	private String fieldRangeStatName(int index) {
		String statname;
		switch (index) {
		case 0:
			statname = "count";
			break;
		case 1:
			statname = "from";
			break;
		case 2:
			statname = "to";
			break;
		case 3:
			statname = "min";
			break;
		case 4:
			statname = "max";
			break;
		case 5:
			statname = "avg";
			break;
		case 6:
			statname = "sum";
			break;
		default:
			statname = "unkown";
		}
		return statname;
	}
	
	private void outputLocate(Map<String, Object> outputmap, Map<String, Object> maps, String keys){
		int dotpos = keys.indexOf(".");
		if(maps==null){
			return;
		}
		if(dotpos<0){
			Map<String, Object> innermap = new HashMap<String, Object>();
			if(keys.contains("{")){
				keys =  keys.substring(1, keys.length()-1); //去除{}
			}
			String[] keyitems= keys.split(",");
			for(String newkey: keyitems){
				outputmap.put(newkey, maps.get(newkey));
			}
			return ;
		}else{
			String key = keys.substring(0, dotpos);
			String restkeys = keys.substring(dotpos+1, keys.length());
			if(!key.contains("[")){
				if(key.contains("{")){
					key =  key.substring(1, key.length()-1); //去除{}
				}
				String[] keyitems= key.split(",");
				
				for(String newkey: keyitems){
					Map<String, Object> innermap = new HashMap<String, Object>();
					outputLocate(innermap, (Map<String, Object>)maps.get(newkey), restkeys);
					outputmap.put(newkey, innermap);
				}
				
//				return outmap;
			}else{
				String newkey = key.substring(1, key.length()-1);  //去除[]
				List<Map<String, Object>> listmaps =(List<Map<String, Object>>)maps.get(newkey);
				List<Map<String, Object>> outlistmap = new ArrayList<Map<String, Object>>();
				if(listmaps!=null){
					for(Map<String, Object> map: listmaps){
						Map<String, Object> ab = new HashMap<String, Object>();
						outputLocate(ab ,map, restkeys);
	//					ab.put(newkey, ab);
						outlistmap.add(ab);
					}
				}
				outputmap.put(newkey, outlistmap);
//				return outlistmap;
			}
		}
	}
	
	public static class ModeSearchRuesult{
		int execode;
		String result="";
		
		public int getExecode() {
			return execode;
		}
		public String getResult() {
			return result;
		}
		
		public void setExecode(int execode) {
			this.execode = execode;
		}
		public void setResult(String result) {
			this.result = result;
		}
	}
}
